/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  

  Aesulate: encrypt RSS/Atom feeds, with in-browser decryption
  
  Copyright (C) 2009 Grahame Bowland <grahame@angrygoats.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

var failure_warning = false;
var pass;

function FindEncrypted()
{
    /* first we scan.. we can't modify the DOM during the scan */
    var d = Array();
    var reg = /^\{AES\}([0-9A-Za-z=/\+]+)/;
    var iterator = document.evaluate('//text()/..', document, null, 
                                     XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
    var thisNode = iterator.iterateNext();
    while (thisNode) {
        var m = reg.exec(thisNode.textContent);
        if (m != null) {
            var mac = m[1].slice(0, 8);
            var dec = m[1].slice(8);
            d.push(Array(thisNode, mac, dec))
        }
        thisNode = iterator.iterateNext();
    }

    /* now go through and decrypt the encrypted text we found */
    if (d.length > 0) {
        if (!pass) {
            pass = prompt("Enter password for AES-ciphered content.");
        }
        if (!pass) {
            // user hit cancel
            return;
        }
        var updated = 0;
        var failures = 0;
        for (var idx=0; idx<d.length; ++idx) {
            var node = d[idx][0];
            var mac = d[idx][1];
            var dec = d[idx][2];
            // verify the MAC
            var our_mac = Sha1HMAC(pass, dec).slice(0, 8);
            if (mac == our_mac) {
                var unc = AESDecryptCtr(dec, pass, 128);
                node.innerHTML = unc;
                ++updated;
            } else {
                ++failures;
            }
        }
        
        if ((failures > 0) && (!failure_warning)) {
            failure_warning = true;
            alert("Some (" + failures + ") AES-encrypted strings could not be decrypted as HMAC verification failed.\n\nYou may have the wrong key, or someone might be doing something nasty.");
        }
    }
    setTimeout(FindEncrypted, 5000);
}

//alert(Sha1HMAC('goat', 'hello world'));
setTimeout(FindEncrypted, 1000);
